home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 140 / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z / Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin / games / oyatsu / src / screen.c < prev    next >
Text File  |  1999-11-22  |  15KB  |  568 lines

  1. /****************************************
  2.  
  3.     推理パズル「おやつタイム」
  4.  
  5.             画面
  6.  
  7.  ****************************************/
  8.  
  9. #include    <stdio.h>
  10. #include    <stdlib.h>
  11. #include    <sys\iocs.h>
  12.  
  13.  
  14. #include    "oyatsu.h"
  15. #include    "screen.h"
  16. #include    "pad.h"
  17. #include    "sprite.h"
  18.  
  19.  
  20. #define    SPRITE_FILE    "OYATSU"            /* スプライトデータ */
  21.  
  22.  
  23. #define    MESSAGE_SX     10                /* メッセージ表示位置 */
  24. #define    MESSAGE_SY      2
  25.  
  26. #define    ANSWER_X     64                /* 回答表示位置 */
  27. #define    ANSWER_Y    330
  28. #define    ANSWER2_X    (ANSWER_X + 216)        /* 解答表示位置 */
  29. #define    ANSWER2_Y    ANSWER_Y
  30. #define    ANSWER_DX     48                /* キャラクタの間隔 */
  31. #define    ANSWER_DY     48
  32.  
  33. #define    SELECT_X    (ANSWER_X + 200)        /* キャラクタ選択用 */
  34. #define    SELECT_Y    (ANSWER_Y + 32)
  35. #define    SELECT_DX     40                /* キャラクタの間隔 */
  36. #define    SELECT_DY     42
  37.  
  38. #define    KETTEI_X    ANSWER_X            /* [決定]ボタン */
  39. #define    KETTEI_Y    (ANSWER_Y + ANSWER_DY*3)
  40.  
  41.  
  42. /*** スプライトナンバー *****/
  43. #define    NUM_CURSOR    0
  44. #define    NUM_ANSWER    (NUM_CURSOR + 4)
  45. #define    NUM_RIGHT_ANS    (NUM_ANSWER + 32)
  46. #define    NUM_OK        (NUM_RIGHT_ANS + 32)
  47.  
  48. /*** スプライトコード *****/
  49. #define    SPR_GIRL    0x100                /* 顔 */
  50. #define    SPR_INPUT    0x999                /* 入力位置 */
  51. #define    SPR_OK        0x59a                /* 決定ボタン */
  52. #define    BG_PATTERN    0x6a0                /* 背景パターン */
  53.  
  54.  
  55. #define    FOOD_MAX    19                /* 菓子の種類 */
  56. #define    BACK_MAX    0x30                /* 背景パターンの数 */
  57.  
  58.  
  59. #define    SPRITE_REG    (unsigned short*)0xeb0000    /* スプライトレジスタアドレス */
  60.  
  61.  
  62. static unsigned short    food_code[FOOD_MAX] = {        /* 菓子スプライト */
  63.                 0xb80, 0xb81, 0xb82, 0xb83, 0xb84, 0xb85, 0xc86, 0xc87,
  64.                 0xc88, 0x789, 0x78a, 0x88b, 0x88c, 0x88d, 0x88e, 0x88f,
  65.                 0xa90, 0xa91, 0xa92
  66.             };
  67.  
  68. static int        cursor_x, cursor_y;        /* 文字表示位置 */
  69.  
  70. static unsigned short    food_kind[GIRL_MAX];        /* 菓子の種類 */
  71.  
  72. static char        sprite_buf[0x8000];        /* スプライトデータ */
  73. static unsigned short    palet_buf[0x100];        /* パレットデータ */
  74.  
  75.  
  76. /**********************
  77.     垂直帰線期間待ち
  78.  **********************/
  79. void    v_synch(void)
  80. {
  81.     pad_synch();                        /* パッド同期処理 */
  82.     rand();                            /* 乱数 */
  83.  
  84.     while ( !(_iocs_b_bpeek((void *)0xe88001) & 0x10) );    /* 垂直帰線期間 */
  85.     while (   _iocs_b_bpeek((void *)0xe88001) & 0x10 );    /* 垂直表示期間 */
  86. }
  87.  
  88. /***************************************
  89.     スプライト描画
  90.     引数     num = スプライト番号
  91.         code = パターンコード
  92.         x, y = 表示位置
  93.  ***************************************/
  94. static
  95. void    put_sprite(int num, unsigned short code, int x, int y)
  96. {
  97.     unsigned short*    p;
  98.  
  99.     p = SPRITE_REG + num*4;                /* スプライトレジスタ */
  100.     *p++ = (unsigned short)x;            /* x座標 */
  101.     *p++ = (unsigned short)y;            /* y座標 */
  102.     *p++ = code;                    /* パターンコード */
  103.     *p   = 3;                    /* プライオリティ */
  104. }
  105.  
  106. /**************************************
  107.     スプライト消去
  108.     引数    num = スプライト番号
  109.  **************************************/
  110. static
  111. void    clear_sprite(int num)
  112. {
  113.     *(SPRITE_REG + num*4 + 3) = 0;            /* スプライト非表示 */
  114. }
  115.  
  116. /***************************************
  117.     スプライト顔描画
  118.     引数     num = スプライト番号
  119.         girl = 人
  120.         x, y = 表示位置
  121.  ***************************************/
  122. static
  123. void    draw_girl_spr(int num, int girl, int x, int y)
  124. {
  125.     int    ssp, code;
  126.  
  127.     ssp = _iocs_b_super(0);                /* スーパーバイザモード */
  128.     if ( girl >= 0 ) {                /* 顔 */
  129.         code = SPR_GIRL + girl*0x120;
  130.         put_sprite(num++, code,        x + 16, y + 16);
  131.         put_sprite(num++, code + 0x01, x + 32, y + 16);
  132.         put_sprite(num++, code + 0x10, x + 16, y + 32);
  133.         put_sprite(num,   code + 0x11, x + 32, y + 32);
  134.     }
  135.     else {                        /* 入力位置 */
  136.         put_sprite(num++, SPR_INPUT, x + 8 + 16, y + 8 + 16);
  137.         clear_sprite(num++);
  138.         clear_sprite(num++);
  139.         clear_sprite(num);
  140.     }
  141.     _iocs_b_super(ssp);                /* ユーザーモード */
  142. }
  143.  
  144. /*********************************
  145.     顔表示
  146.     引数    girl = 人
  147.          exp = 表情
  148.         x, y = 表示位置
  149.  *********************************/
  150. static
  151. void    draw_girl(int girl, int exp, int x, int y)
  152. {
  153.     int    ssp;
  154.     char*        pat;
  155.     unsigned short*    pal;
  156.  
  157.     ssp = _iocs_b_super(0);                /* スーパーバイザモード */
  158.     pat = sprite_buf + ((SPR_GIRL % 0x100) + girl*0x20 + exp*2)*0x80;
  159.                                 /* パターン */
  160.     pal = palet_buf + (SPR_GIRL/0x100 - 1 + girl)*0x10;    /* パレット */
  161.     draw_g_sprite(x,      y,      pat,             pal);
  162.     draw_g_sprite(x + 16, y,      pat + 0x01*0x80, pal);
  163.     draw_g_sprite(x,      y + 16, pat + 0x10*0x80, pal);
  164.     draw_g_sprite(x + 16, y + 16, pat + 0x11*0x80, pal);
  165.     _iocs_b_super(ssp);                /* ユーザーモード */
  166. }
  167.  
  168. /*********************************
  169.     菓子表示
  170.     引数    food = 菓子
  171.         x, y = 表示位置
  172.  *********************************/
  173. static
  174. void    draw_food(int food, int x, int y)
  175. {
  176.     int    ssp, code;
  177.  
  178.     ssp = _iocs_b_super(0);                /* スーパーバイザモード */
  179.     code = food_kind[food];                /* スプライトコード */
  180.     draw_g_sprite2(x, y, sprite_buf + (code % 0x100)*0x80,
  181.                         palet_buf + (code/0x100 - 1)*0x10);
  182.     _iocs_b_super(ssp);                /* ユーザーモード */
  183. }
  184.  
  185. /************************************
  186.     メッセージ表示
  187.     引数    girl = 発言者番号
  188.          mes = メッセージ
  189.          num = 要素番号
  190.     戻り値    表示位置
  191.  ***********************************/
  192. int    print_message(int girl, MESSAGE* mes, int* num)
  193. {
  194.     char    buf[80], *p0, *p1;
  195.     int    pos;
  196.  
  197.     pos = cursor_y*16 - 12;
  198.     draw_girl(girl, mes->exp, MESSAGE_SX*8 - 48, pos);    /* 発言者表示 */
  199.  
  200.     _iocs_b_locate(cursor_x - 2, cursor_y);
  201.     _iocs_b_print("「");
  202.     p0 = mes->str;                    /* メッセージ文章 */
  203.     while (1) {
  204.         _iocs_b_locate(cursor_x, cursor_y);    /* 表示位置 */
  205.         p1 = buf;
  206.         while ( (unsigned char)*p0 >= 0x80 ) {
  207.             *p1++ = *p0++;
  208.             *p1++ = *p0++;
  209.             cursor_x += 2;
  210.         }
  211.         *p1 = '\0';
  212.         _iocs_b_print(buf);            /* 文字列表示 */
  213.         if ( *p0 == '\0' ) {            /* 終端 */
  214.             break;
  215.         }
  216.         if ( *p0 == '\n' ) {            /* 改行 */
  217.             cursor_x = MESSAGE_SX;
  218.             cursor_y += 2;
  219.         }
  220.         else if ( *p0 == '#' ) {        /* 菓子 */
  221.             p0++;
  222.             draw_food(num[*p0 - '0'], cursor_x*8, cursor_y*16 - 12);
  223.             cursor_x += 4;
  224.         }
  225.         else if ( *p0 == '$' ) {        /* 人 */
  226.             p0++;
  227.             draw_girl(num[*p0 - '0'], 0, cursor_x*8, cursor_y*16 - 12);
  228.             cursor_x += 4;
  229.         }
  230.         p0++;
  231.     }
  232.     _iocs_b_print("」");
  233.     cursor_x = MESSAGE_SX;
  234.     cursor_y += 3;
  235.  
  236.     return    pos;
  237. }
  238.  
  239. /*********************************
  240.     答表示
  241.     引数    kind = 0 : 回答
  242.                1 : 解答
  243.          ans = 答
  244.  *********************************/
  245. void    draw_answer(int kind, int ans[ELM_MAX][GIRL_MAX])
  246. {
  247.     int    i, x, num;
  248.  
  249.     if ( kind == 0 ) {                /* 回答 */
  250.         num = NUM_ANSWER;
  251.           x = ANSWER_X;
  252.     }
  253.     else {                        /* 解答 */
  254.         num = NUM_RIGHT_ANS;
  255.           x = ANSWER2_X;
  256.     }
  257.     for (i = 0; i < GIRL_MAX; i++) {
  258.         draw_food(i, x, ANSWER_Y);            /* 菓子 */
  259.         draw_girl_spr(num, ans[ELM_BUY][i], x, ANSWER_Y + ANSWER_DY);    /* 買った人 */
  260.         num += 4;
  261.         draw_girl_spr(num, ans[ELM_EAT][i], x, ANSWER_Y + ANSWER_DY*2);    /* 食べた人 */
  262.         num += 4;
  263.         x += ANSWER_DX;
  264.     }
  265. }
  266.  
  267. /**************************************
  268.     決定ボタン描画
  269.     引数    f = 全て入力されたか
  270.  **************************************/
  271. static
  272. void    draw_ok_button(Bool f)
  273. {
  274.     int    ssp, i;
  275.  
  276.     ssp = _iocs_b_super(0);                /* スーパーバイザモード */
  277.     if ( f ) {                    /* ボタン描画 */
  278.         for (i = 0; i < 6; i++) {
  279.             put_sprite(NUM_OK + i, SPR_OK + i, KETTEI_X + (i % 3)*16 + 16,
  280.                                 KETTEI_Y + i/3*16 + 16);
  281.         }
  282.     }
  283.     else {                        /* ボタン消去 */
  284.         for (i = 0; i < 6; i++) {
  285.             clear_sprite(NUM_OK + i);
  286.         }
  287.     }
  288.     _iocs_b_super(ssp);                /* ユーザーモード */
  289. }
  290.  
  291. /*********************************************
  292.     入力処理
  293.     引数       ans = 回答バッファ
  294.         select = 選択キャラクタ
  295.              f = 全て入力されたか
  296.           x, y = マウスカーソル位置
  297.     戻り値    選択キャラクタ
  298.         -1 : 入力完了
  299.  *********************************************/
  300. static
  301. int    input_sub(int ans[ELM_MAX][GIRL_MAX], int select, Bool f, int x, int y)
  302. {
  303.     int    i, m, n;
  304.  
  305.     if ( f && (x >= KETTEI_X) && (x < KETTEI_X + 16*3)
  306.                     && (y >= KETTEI_Y) && (y < KETTEI_Y + 16*2) ) {
  307.         return    -1;                /* 入力完了 */
  308.     }
  309.  
  310.     m = x - (ANSWER_X - (ANSWER_DX - 32)/2);
  311.     n = y - (ANSWER_Y + ANSWER_DY - (ANSWER_DY - 32)/2);
  312.     if ( (m >= 0) && (m < GIRL_MAX*ANSWER_DX) && (n >= 0) && (n < 2*ANSWER_DY) ) {
  313.                             /* 回答入力 */
  314.         m /= ANSWER_DX;
  315.         n /= ANSWER_DY;
  316.         for (i = 0; i < GIRL_MAX; i++) {
  317.             if ( ans[n][i] == select ) {
  318.                 ans[n][i] = -1;
  319.             }
  320.         }
  321.         ans[n][m] = select;
  322.         return    select;
  323.     }
  324.  
  325.     m = x - (SELECT_X - (SELECT_DX - 32)/2);
  326.     n = y - (SELECT_Y - (SELECT_DY - 32)/2);
  327.     if ( (m >= 0) && (m < (GIRL_MAX/2)*SELECT_DX) && (n >= 0) && (n < 2*SELECT_DY) ) {
  328.                             /* キャラクタ選択 */
  329.         return    ((n/SELECT_DY)*(GIRL_MAX/2) + m/SELECT_DX);
  330.     }
  331.     return    select;
  332. }
  333.  
  334. /************************************
  335.     回答入力
  336.     引数    ans = 回答バッファ
  337.     戻り値     0 : 入力完了
  338.         -1 : ゲーム終了
  339.  ************************************/
  340. int    input_answer(int ans[ELM_MAX][GIRL_MAX])
  341. {
  342.     static struct _symbolptr     katta = {ANSWER_X - 36, ANSWER_Y + ANSWER_DY + 4,
  343.                          "買", 1, 1, 0xfd38, 2, 0},
  344.                     tabeta = {ANSWER_X - 36, ANSWER_Y + ANSWER_DY*2 + 4,
  345.                          "食", 1, 1, 0xffe8, 2, 0};
  346.     int    ssp;
  347.     int    i, j, *p, select;
  348.     Bool    f;
  349.  
  350.     p = &ans[0][0];                    /* 回答バッファ */
  351.     for (i = 0; i < ELM_MAX*GIRL_MAX; i++) {
  352.         *p++ = -1;                /* 未入力 */
  353.     }
  354.     select= 0;                    /* 選択中キャラクタ */
  355.  
  356.     for (i = 0; i < GIRL_MAX; i++) {        /* 選択用キャラクタ表示 */
  357.         draw_girl_spr(NUM_RIGHT_ANS + i*4, i,
  358.                     SELECT_X + (i % (GIRL_MAX/2))*SELECT_DX,
  359.                     SELECT_Y + (i/(GIRL_MAX/2))*SELECT_DY);
  360.     }
  361.     _iocs_symbol(&katta);                /* "買" */
  362.     _iocs_symbol(&tabeta);                /* "食" */
  363.  
  364.     while (1) {
  365.         v_synch();                /* 垂直同期 */
  366.         if ( esc_key ) {
  367.             return    -1;            /* ゲーム終了 */
  368.         }
  369.  
  370.         p = &ans[0][0];                /* 回答バッファ */
  371.         f = TRUE;
  372.         for (i = 0; i < ELM_MAX*GIRL_MAX; i++) {
  373.             if ( *p++ < 0 ) {        /* 未入力 */
  374.                 f = FALSE;
  375.                 break;
  376.             }
  377.         }
  378.         draw_ok_button(f);            /* 決定ボタン */
  379.  
  380.         draw_answer(0, ans);            /* 回答表示 */
  381.         get_ms_pos(&i, &j);            /* マウスカーソル位置 */
  382.         draw_girl_spr(NUM_CURSOR, select, i - 16, j - 16);    /* カーソル表示 */
  383.  
  384.         if ( get_push() & PAD_A ) {        /* 左クリック */
  385.             if ( (select = input_sub(ans, select, f, i, j)) < 0 ) {
  386.                 break;
  387.             }
  388.         }
  389.         if ( get_push() & PAD_B ) {        /* 右クリック */
  390.             select = (select + 1) % GIRL_MAX;    /* 選択キャラクター切り替え */
  391.         }
  392.     }
  393.  
  394.     ssp = _iocs_b_super(0);                /* スーパーバイザモード */
  395.     for (i = 0; i < 4; i++) {            /* カーソル消去 */
  396.         clear_sprite(NUM_CURSOR + i);
  397.     }
  398.     _iocs_b_super(ssp);                /* ユーザーモード */
  399.  
  400.     return    0;
  401. }
  402.  
  403. /******************
  404.     「正解」表示
  405.  ******************/
  406. void    draw_atari(void)
  407. {
  408.     static struct _symbolptr    atari = {ANSWER_X + 28, ANSWER_Y - 20,
  409.                              "正 解", 2, 3, 0x67d8, 2, 0};
  410.  
  411.     _iocs_symbol(&atari);                /* "正解" */
  412. }
  413.  
  414. /********************************
  415.     条件に合っていない
  416.     引数    pos = 表示位置
  417.  ********************************/
  418. void    draw_mujun1(int pos)
  419. {
  420.     static struct _boxptr    box = {MESSAGE_SX*8 - 50, 0, MESSAGE_SX*8 - 14, 0,
  421.                                     0x67d8, 0xffff};
  422.  
  423.     box.y1 = pos - 3;
  424.     box.y2 = pos + 35;
  425.     _iocs_box(&box);                /* 赤枠で囲む */
  426. }
  427.  
  428. /********************************
  429.     前提に合っていない
  430.     引数    num = 菓子番号
  431.  ********************************/
  432. void    draw_mujun2(int num)
  433. {
  434.     static struct _boxptr    box = {0, ANSWER_Y + ANSWER_DY - 3,
  435.                     0, ANSWER_Y + ANSWER_DY*2 + 35, 0x67d8, 0xffff};
  436.  
  437.     box.x1 = ANSWER_X + num*ANSWER_DX - 2;
  438.     box.x2 = ANSWER_X + num*ANSWER_DX + 34;
  439.     _iocs_box(&box);                /* 赤枠で囲む */
  440. }
  441.  
  442. /****************
  443.     画面クリア
  444.  ****************/
  445. void    clear_screen(void)
  446. {
  447.     int    ssp;
  448.     char*        pat;
  449.     unsigned short*    pal;
  450.     int        i, j;
  451.  
  452.     _iocs_b_clr_al();                /* テキスト画面クリア */
  453.     cursor_x = MESSAGE_SX;                /* カーソル位置 */
  454.     cursor_y = MESSAGE_SY;
  455.  
  456.     ssp = _iocs_b_super(0);                /* スーパーバイザモード */
  457.     for (i = 0; i < 0x80; i++) {
  458.         clear_sprite(i);            /* スプライト非表示 */
  459.     }
  460.  
  461.     pat = sprite_buf + ((BG_PATTERN % 0x100) + rnd(BACK_MAX))*0x80;        /* パターン */
  462.     pal = palet_buf + (BG_PATTERN/0x100 - 1)*0x10;                /* パレット */
  463.     for (i = 0; i < 0x200; i += 0x20) {        /* 背景クリア */
  464.         for (j = 0; j < 0x200; j += 0x20) {
  465.             draw_g_sprite2(j, i, pat, pal);
  466.         }
  467.     }
  468.     _iocs_b_super(ssp);                /* ユーザーモード */
  469. }
  470.  
  471. /**************
  472.     菓子設定
  473.  **************/
  474. void    set_food(void)
  475. {
  476.     unsigned short    code;
  477.     int        i, j;
  478.  
  479.     for (i = 0; i < GIRL_MAX; i++) {
  480.         do {
  481.             code = food_code[rnd(FOOD_MAX)];    /* 菓子スプライト */
  482.             for (j = 0; j < i; j++) {
  483.                 if ( code == food_kind[j] ) {    /* 重複 */
  484.                     break;
  485.                 }
  486.             }
  487.         } while ( j < i );
  488.         food_kind[i] = code;                /* 使用する菓子の種類 */
  489.     }
  490. }
  491.  
  492. /****************************************
  493.     スプライトデータ読み込み
  494.     引数    fname = ファイルネーム
  495.     戻り値    0 : 読み込み完了
  496.         1 : 読み込み失敗
  497.  ****************************************/
  498. static
  499. int    load_sprite(char* fname)
  500. {
  501.     FILE*    fp;
  502.     char    buf[256], *p;
  503.     unsigned short*    c;
  504.     int    i, j, size;
  505.  
  506.     _iocs_sp_init();                /* スプライト画面初期化 */
  507.     _iocs_sp_on();                    /* スプライト画面表示 */
  508.  
  509.     sprintf(buf, "%s.SP", fname);            /* パターンデータ */
  510.     if ( (fp = fopen(buf, "rb")) == NULL ) {
  511.         eprintf("パターンファイル \"%s\" が開けません\n", buf);
  512.         return    1;
  513.     }
  514.     printf("\"%s\" 読み込み中\n", buf);
  515.     size = fread(sprite_buf, 0x80, 0x100, fp);
  516.     fclose(fp);
  517.  
  518.     for (i = 0, p = sprite_buf; i < size; i++, p += 0x80) {
  519.         _iocs_sp_defcg(i, 1, p);        /* スプライト定義 */
  520.     }
  521.  
  522.     sprintf(buf, "%s.PAL", fname);            /* パレットデータ */
  523.     if ( (fp = fopen(buf, "rb")) == NULL ) {
  524.         eprintf("パレットファイル \"%s\" が開けません\n", buf);
  525.         return    1;
  526.     }
  527.     printf("\"%s\" 読み込み中\n", buf);
  528.     size = fread(palet_buf, sizeof(short)*0x10, 0x0f, fp);
  529.     fclose(fp);
  530.  
  531.     c = palet_buf;
  532.     for (j = 0; j < size; j++) {
  533.         for (i = 0; i < 0x10; i++) {
  534.             _iocs_spalet(i + 0x80, j + 1, (int)*c++);    /* パレット定義 */
  535.         }
  536.     }
  537.  
  538.     _iocs_b_clr_al();                /* 画面クリア */
  539.     return    0;
  540. }
  541.  
  542. /******************
  543.     マウス初期化
  544.  ******************/
  545. static
  546. void    init_mouse(void)
  547. {
  548.     _iocs_ms_init();                /* マウス初期化 */
  549.     _iocs_ms_curst(ANSWER_X, ANSWER_Y);        /* マウスカーソル座標 */
  550.     _iocs_ms_curof();                /* マウスカーソルOFF */
  551. }
  552.  
  553. /********************************
  554.     画面初期化
  555.     戻り値    0 : 初期化完了
  556.         1 : 初期化失敗
  557.  ********************************/
  558. int    init_screen(void)
  559. {
  560.     init_mouse();                    /* マウス初期化 */
  561.     if ( load_sprite(SPRITE_FILE) ) {        /* スプライト読み込み */
  562.         return    1;
  563.     }
  564.     _iocs_b_bpoke((void*)0xe82500, 0x12);        /* プライオリティ設定 */
  565.     return    0;
  566. }
  567.  
  568. /****************** End of File *************************************************/